#include "include.h"

#define serial_num(a) ((a) * 256)



#define MAX_SUB_PKG_CNT_IN_FLASH 0x100  //( 0x100 0000 / 256 )

uint8_t sync_flash_buf[MAX_SUB_PKG_CNT_IN_FLASH];
//EXFLASH的循环队列入队
void sync_buf_write_enqueue( CYCLE_QUEUE *cycle_queue )
{
  cycle_queue->tail += cycle_queue->write_len;
  cycle_queue->tail %= Cycle_Queue_Len_Max;
  HAL_RTCEx_BKUPWrite( &hrtc, RTC_BKP_DR2, cycle_queue->tail );
}
//EXFLASH的循环队列出队
void sync_buf_read_dequeue( CYCLE_QUEUE *cycle_queue )
{
  cycle_queue->head += cycle_queue->read_len;
  cycle_queue->head %= Cycle_Queue_Len_Max;
  HAL_RTCEx_BKUPWrite( &hrtc, RTC_BKP_DR3, cycle_queue->head );
}


//往EXFLASH中写入一包数据
void push_sub_package_into_exflash( CYCLE_QUEUE *cycle_queue, unsigned char *prepare_data  )
{
  uint32_t i;
  memset( cycle_queue->write_data, NULL, Cycle_Queue_Data_Size );

  cycle_queue->write_len = prepare_data[Package_Len_Pos]+Package_Aside_From_User_Data;

  for( i = cycle_queue->tail; i < cycle_queue->write_len; i++ )
  {
    // 如果目前写入的数据会覆盖之前写人数据则将之前的整包数据出队。
    if( i == cycle_queue->head )
    {
      from_exflash_read_package( &rk.flash_cycle_queue );
      sync_buf_read_dequeue( &rk.flash_cycle_queue );
      HAL_Delay(10);
    }
  }
  memcpy( cycle_queue->write_data, prepare_data, cycle_queue->write_len );

  // 循环队列
  // write data
  if( cycle_queue->tail + cycle_queue->write_len <= Cycle_Queue_Len_Max )
  {
    w25qxx_write( cycle_queue->write_data, cycle_queue->tail, cycle_queue->write_len );
  }
  else if( cycle_queue->tail + cycle_queue->write_len > Cycle_Queue_Len_Max )
  {
    w25qxx_write( cycle_queue->write_data, cycle_queue->tail, Cycle_Queue_Len_Max - cycle_queue->tail );
    w25qxx_write( cycle_queue->write_data + (Cycle_Queue_Len_Max - cycle_queue->tail), 0x00, cycle_queue->write_len - (Cycle_Queue_Len_Max - cycle_queue->tail) );
  }
  sync_buf_write_enqueue( &rk.flash_cycle_queue );
  HAL_Delay(10);
}

//从EXFLASH中读出一包数据
void from_exflash_read_package( CYCLE_QUEUE *cycle_queue )
{
  uint8_t package_len;

  memset( cycle_queue->read_data, 0,  Cycle_Queue_Data_Size );

  // get next package len
  if( (cycle_queue->head + 1) <= Cycle_Queue_Len_Max )
  {
    w25qxx_read( &package_len, (cycle_queue->head + 1), 1 );
  }
  else
  {
    w25qxx_read( &package_len, 0x00, 1 );
  }
  cycle_queue->read_len = package_len + Package_Aside_From_User_Data;

  // read data
  if( cycle_queue->head + cycle_queue->read_len <= Cycle_Queue_Len_Max )
  {
      w25qxx_read( cycle_queue->read_data, cycle_queue->head, cycle_queue->read_len );
  }
  else if( cycle_queue->head + cycle_queue->read_len > Cycle_Queue_Len_Max )
  {
    w25qxx_read( cycle_queue->read_data, cycle_queue->head, Cycle_Queue_Len_Max - cycle_queue->head );
    w25qxx_read( cycle_queue->read_data + (Cycle_Queue_Len_Max - cycle_queue->head), 0x00, cycle_queue->read_len - (Cycle_Queue_Len_Max - cycle_queue->read_len) );
  }
}

/* 超参数 */
unsigned char initflag_get(void)
{
  w25qxx_read( (uint8_t *)&rk.init_flag, Extflash_Addr_Init_Flag, Addr_Init_Flag_Size );
  HAL_Delay(50);
  return rk.init_flag;
}

void initflag_set( unsigned char flag )
{
  rk.init_flag = flag;
  w25qxx_write_256_bytes( (uint8_t *)&rk.init_flag, Extflash_Addr_Init_Flag );
  HAL_Delay(50);
}
uint16_t temp = 0;
void hyper_parameter_set( void )
{
  w25qxx_write_256_bytes( (uint8_t *)&rk.hyper_parameter, Extflash_Addr_Hyper_Parameter );
  HAL_Delay(50);
}

void hyper_parameter_get( void )
{
  w25qxx_read( (uint8_t *)&rk.hyper_parameter, Extflash_Addr_Hyper_Parameter, Addr_Hyper_Parameter_Size );
  HAL_Delay(50);
}
void parameter_set( void )
{
  w25qxx_write_256_bytes( (uint8_t *)&rk.parameter, Extflash_Addr_Parameter );
  HAL_Delay(50);
}
void parameter_get( void )
{
  w25qxx_read( (uint8_t *)&rk.parameter, Extflash_Addr_Parameter, Addr_Parameter_Size );
  HAL_Delay(50);
}

void app1_start_count_set( unsigned char count )
{
  iap_btld.app1_start_count = count;
  HAL_RTCEx_BKUPWrite( &hrtc, RTC_BKP_DR1, iap_btld.app1_start_count );
  HAL_Delay(10);
}

void app1_start_count_get( void )
{
  iap_btld.app1_start_count = HAL_RTCEx_BKUPRead( &hrtc, RTC_BKP_DR1);
  HAL_Delay(10);
  if( iap_btld.app1_start_count == 0xFF )
  {
    iap_btld.app1_start_count = 0x00;
  }
}



